package com.sf.sgs.sessionevaluate.service.impl;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Component;

import com.sf.sgs.sessionevaluate.controller.dto.req.QuestionOptionReq;
import com.sf.sgs.sessionevaluate.controller.dto.req.QuestionReq;
import com.sf.sgs.sessionevaluate.controller.dto.req.QuestionnaireCompositeReq;
import com.sf.sgs.sessionevaluate.controller.dto.resp.QuestionOptionResp;
import com.sf.sgs.sessionevaluate.controller.dto.resp.QuestionResp;
import com.sf.sgs.sessionevaluate.controller.dto.resp.QuestionnaireCompositeResp;
import com.sf.sgs.sessionevaluate.controller.dto.resp.QuestionnaireResp;
import com.sf.sgs.sessionevaluate.dao.IQuestionDao;
import com.sf.sgs.sessionevaluate.dao.IQuestionOptionDao;
import com.sf.sgs.sessionevaluate.dao.IQuestionnaireDao;
import com.sf.sgs.sessionevaluate.domain.Question;
import com.sf.sgs.sessionevaluate.domain.QuestionOption;
import com.sf.sgs.sessionevaluate.domain.Questionnaire;
import com.sf.sgs.sessionevaluate.service.IQuestionOptionService;
import com.sf.sgs.sessionevaluate.service.IQuestionService;
import com.sf.sgs.sessionevaluate.service.IQuestionnaireService;
import com.sf.sgs.sessionevaluate.util.BeanUtil;

@Component
public class QuestionnaireServiceImpl extends TransactionalService implements IQuestionnaireService {

	@Autowired
	private IQuestionnaireDao questionnaireDao;

	@Autowired
	private IQuestionDao questionDao;

	@Autowired
	private IQuestionOptionDao questionOptionDao;

	@Autowired
	private IQuestionService questionService;

	@Autowired
	private IQuestionOptionService questionOptionService;

	@Override
	public void save(QuestionnaireCompositeReq questionnaireCompositeReq) {
		// 分享主体信息
		Questionnaire questionnaire = new Questionnaire();
		BeanUtils.copyProperties(questionnaireCompositeReq.getQuestionnaireReq(), questionnaire);
		questionnaire.setState(0);
		Date now = new Date();
		questionnaire.setModifyDate(now);
		questionnaire.setCreateDate(now);
		questionnaireDao.save(questionnaire);

		// 保存题干
		List<QuestionReq> questionReqList = questionnaireCompositeReq.getQuestionReqList();
		questionReqList.stream().forEach(new Consumer<QuestionReq>() {

			@Override
			public void accept(QuestionReq questionReq) {
				Question question = convertQuestionReq(questionReq, questionnaire);
				questionDao.save(question);

				// 保存选项
				List<QuestionOptionReq> questionOptionReqList = questionReq.getQuestionOptionReqList();
				Iterator<QuestionOption> questionOptionIterator = questionOptionReqList.stream().map(o -> convertQuestionOptionReq(o, question)).iterator();
				questionOptionDao.save(new Iterable<QuestionOption>() {

					@Override
					public Iterator<QuestionOption> iterator() {
						return questionOptionIterator;
					}
				});
			}
		});

	}

	private Question convertQuestionReq(QuestionReq questionReq, Questionnaire questionnaire) {
		Question question = new Question();
		BeanUtils.copyProperties(questionReq, question, "questionOptionReqList");
		question.setQuestionnaire(questionnaire);
		Date now = new Date();
		question.setModifyDate(now);
		question.setCreateDate(now);
		return question;
	}

	private QuestionOption convertQuestionOptionReq(QuestionOptionReq questionOptionReq, Question question) {
		QuestionOption questionOption = new QuestionOption();
		BeanUtils.copyProperties(questionOptionReq, questionOption);
		questionOption.setQuestion(question);
		Date now = new Date();
		questionOption.setModifyDate(now);
		questionOption.setCreateDate(now);
		return questionOption;
	}

	@Override
	public Questionnaire getByIdAndType(Long id, Integer type) {
		Questionnaire questionnaire = new Questionnaire();
		questionnaire.setId(id);
		questionnaire.setType(type);
		Example<Questionnaire> example = Example.of(questionnaire);
		List<Questionnaire> list = questionnaireDao.findAll(example);
		return list.isEmpty() ? null : list.get(0);
	}

	@Override
	public QuestionnaireCompositeResp getCompositeInfo(Long id, Integer type) {

		Questionnaire uestionnaire = getByIdAndType(id, type);
		if (uestionnaire == null) {
			return null;
		}

		List<Question> questionList = questionService.getByQuestionnaireId(id);
		List<QuestionResp> questionRespList = questionList.parallelStream().map(new Function<Question, QuestionResp>() {

			@Override
			public QuestionResp apply(Question question) {
				List<QuestionOption> questionOptionList = questionOptionService.getByQuestionId(question.getId());
				List<QuestionOptionResp> questionOptionRespList = questionOptionList.parallelStream().map(o -> BeanUtil.copyProperties(o, QuestionOptionResp.class)).collect(Collectors.toList());
				QuestionResp questionResp = BeanUtil.copyProperties(question, QuestionResp.class);
				questionResp.setQuestionOptionResp(questionOptionRespList);
				return questionResp;
			}

		}).collect(Collectors.toList());

		QuestionnaireCompositeResp questionnaireCompositeResp = new QuestionnaireCompositeResp();
		QuestionnaireResp questionnaireResp = BeanUtil.copyProperties(uestionnaire, QuestionnaireResp.class);
		questionnaireCompositeResp.setQuestionnaireResp(questionnaireResp);
		questionnaireCompositeResp.setQuestionRespList(questionRespList);
		return questionnaireCompositeResp;
	}

	@Override
	public List<Questionnaire> getList(int type) {
		Questionnaire questionnaire = new Questionnaire();
		questionnaire.setType(type);
		Example<Questionnaire> example = Example.of(questionnaire);
		Sort sort = new Sort(Direction.ASC, "createDate");
		List<Questionnaire> list = questionnaireDao.findAll(example, sort);
		return list;
	}

}
